program main

    use, intrinsic :: iso_c_binding, only: newline => c_new_line
    use seakeeping_time, only: tic, toc
    implicit none

    character(*), parameter :: file1 = 'app/main.f90'
    character(*), parameter :: file2 = 'src/io.f90'
    integer :: i, N = 400
    real(8) :: t1, t2
    logical, parameter :: print = .false.

    call tic()
    do i = 1, N
        call default_read()
    end do
    call toc(t1)
    print *, 'fpm: ', t1, 's'

    call tic()
    do i = 1, N
        call read_all()
    end do
    call toc(t2)
    print *, 'toml-f: ', t2, 's'

    print *, 'toml-f / fpm = ', t1/t2, ' with files ', N*2

contains

    !> 默认读取方式
    subroutine default_read()
        use fpm, only: read_lines, string_t
        integer :: u1, u2
        type(string_t), allocatable :: lines(:)

        open (newunit=u1, file=file1, status='old')
        open (newunit=u2, file=file2, status='old')
        lines = read_lines(u1)
        if (print) call prt(lines)
        deallocate (lines)
        lines = read_lines(u2)
        if (print) call prt(lines)
        close (u1)
        close (u2)

    end subroutine default_read

    !> 一次性读取
    subroutine read_all()
        use tomlf_utils_io, only: read_whole_file
        use fpm, only: string_t
        integer :: stat
        type(string_t), allocatable :: lines(:)
        character(:), allocatable :: text

        call read_whole_file(file1, text, stat)
        call text2strings(text, lines)
        if (print) call prt(lines)
        deallocate (lines)
        call read_whole_file(file2, text, stat)
        call text2strings(text, lines)
        if (print) call prt(lines)

    end subroutine read_all

    pure subroutine text2strings(text, lines)
        use fpm, only: string_t
        character(len=*), intent(in) :: text
        type(string_t), allocatable, intent(out) :: lines(:)
        integer :: i, j, k, n, nlines
        character(len=:), allocatable :: line

        n = len(text)
        nlines = 0
        do i = 1, n
            if (text(i:i) == newline) nlines = nlines + 1
        end do
        allocate (lines(nlines))
        i = 1
        k = 1
        do j = 1, nlines
            do
                if (text(i:i) == newline) exit
                i = i + 1
            end do
            lines(j)%s = text(k:i - 1)
            k = i + 1
            i = k
        end do

    end subroutine text2strings

    subroutine prt(lines)
        use fpm, only: string_t
        type(string_t), intent(in) :: lines(:)
        integer :: i, n

        n = size(lines)
        do i = 1, n
            print *, lines(i)%s
        end do
    end subroutine prt

end program main
